﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using Studio77.SuperLink.Core;
using Studio77.SuperLink.Entities;
using Studio77.SuperLink.Pages;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
using Studio77.SuperLink.Other;

namespace Studio77.SuperLink.Views
{
    public class LinkGameCanvas : Canvas
    {
        private int[,] gameData;
        private Dictionary<int, LinkCard> linkCards = new Dictionary<int, LinkCard>();
        private Random r = new Random(DateTime.Now.Millisecond);
        private LinkCard selectCard = null;
        private int rowCount, columnCount, cardCount, currentClearCount;
        private Polyline linkLine = new Polyline();
        //private ComboBlock combo = new ComboBlock();
        private double perWidth, perHeight;
        private GameArrangeType arrangeType = GameArrangeType.None;

        private object syncObjClickProcess = new object();
        private object syncObjLineCardProcess = new object();

        /// <summary>
        /// 连连看项变化范围
        /// </summary>
        private int itemChangeBase = 10;

        private int itemStartBase = 0;

        ImageBrush ib1;
        ImageBrush ib2;
        ImageBrush ib3;

        public LinkGameCanvas()
        {
            ib1 = new ImageBrush();
            string uri = "/Images/linkline1.jpg";
            BitmapImage bitmap = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute));
            ib1.Stretch = Stretch.UniformToFill;
            ib1.ImageSource = bitmap;

            ib2 = new ImageBrush();
            string uri2 = "/Images/linkline2.jpg";
            BitmapImage bitmap2 = new BitmapImage(new Uri(uri2, UriKind.RelativeOrAbsolute));
            ib2.Stretch = Stretch.UniformToFill;
            ib2.ImageSource = bitmap2;


            ib3 = new ImageBrush();
            string uri3 = "/Images/linkline3.jpg";
            BitmapImage bitmap3 = new BitmapImage(new Uri(uri3, UriKind.RelativeOrAbsolute));
            ib3.Stretch = Stretch.UniformToFill;
            ib3.ImageSource = bitmap3;
        }

        public void StartNewGame(int row, int column, int itemChangeBase, int itemStartBase, GameArrangeType arrangeType)
        {
            selectCard = null;
            this.arrangeType = arrangeType;
            rowCount = row;
            columnCount = column;
            cardCount = row * column;
            currentClearCount = 0;

            this.itemChangeBase = itemChangeBase;
            this.itemStartBase = itemStartBase;

            //初始化游戏数据
            gameData = new int[row + 2, column + 2];
            RamdomGameData();
            linkLine.StrokeThickness = 8;
            linkLine.Stroke = ib1;

            if (row == 12)
            {
                linkLine.StrokeThickness = 6;
            }
            else if (row == 15)
            {
                linkLine.StrokeThickness = 4;
            }
            else if (row == 18)
            {
                linkLine.StrokeThickness = 2;
            }



            RefreshCards();
        }

        private void RefreshCards()
        {
            //初始化界面
            linkCards.Clear();
            this.Children.Clear();
            if(selectCard != null)
            {
                selectCard.SetUnSelectedCard();
            }
            selectCard = null;
            perWidth = this.Width / columnCount;
            perHeight = this.Height / rowCount;
            //do layout
            for (int i = 1; i <= rowCount; i++)
            {
                for (int j = 1; j <= columnCount; j++)
                {
                    if (gameData[i, j] >= 0)
                    {
                        LinkCard card = new LinkCard();
                        Canvas.SetTop(card, (i - 1) * perWidth);
                        Canvas.SetLeft(card, (j - 1) * perHeight);
                        card.Width = perWidth;
                        card.Height = perHeight;
                        card.X = i;
                        card.Y = j;
                        card.SetCardValue(gameData[i, j], columnCount);
                        card.MouseLeftButtonDown += new MouseButtonEventHandler(card_MouseLeftButtonDown);
                        Children.Add(card);
                        linkCards.Add(i * columnCount + j, card);
                    }
                }
            }

            //combo.Height = perHeight / 2;
            //combo.Width = combo.Height * 4;
        }

        void card_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (GamePage.Instance.gameStatus != 1)
            {
                return;
            }
            lock (syncObjClickProcess)
            {
                //click game cards
                LinkCard card = (LinkCard)sender;
                if (selectCard == null)
                {
                    //No Selected Card
                    card.SetSelectedCard();
                    selectCard = card;
                    SoundManager.PlayEffect(SoundManager.Click);
                }
                else if (card != selectCard)
                {
                    if (gameData[card.X, card.Y] == -1 || gameData[selectCard.X, selectCard.Y] == -1)
                    {
                        selectCard = null;
                        return;
                    }

                    //Selected one card, should judgment two card
                    //1.two card with same content
                    if (card.Value == selectCard.Value)
                    {
                        //2.can lined
                        if (LLKLogicHelper.CanEliminate(gameData, card.X, card.Y, selectCard.X, selectCard.Y, rowCount, columnCount))
                        {
                            gameData[card.X, card.Y] = -1;
                            gameData[selectCard.X, selectCard.Y] = -1;
                            //连线操作
                            SetLinkLine(card.X, card.Y, selectCard.X, selectCard.Y);
                            card.SetSelectedCard();

                            //show combo
                            //if (GamePage.Instance.comboCount >= 2)
                            //{
                            //    combo.setCombo(GamePage.Instance.comboCount);
                            //    Canvas.SetTop(combo, (card.X - 0.5) * perWidth);
                            //    Canvas.SetLeft(combo, (card.Y - 0.5) * perHeight);
                            //    if (!this.Children.Contains(combo))
                            //    {
                            //        this.Children.Add(combo);
                            //    }

                            //}

                            MyDispatcherTimer timer = new MyDispatcherTimer();
                            timer.Interval = TimeSpan.FromMilliseconds(120);
                            timer.card1 = selectCard;
                            timer.card2 = card;
                            selectCard = null;

                            timer.Tick += (object sender2, EventArgs ee) =>
                            {
                                lock (syncObjLineCardProcess)
                                {
                                    MyDispatcherTimer myTimer = sender2 as MyDispatcherTimer;
                                    myTimer.Stop();
                                    LinkCard mySelectCard = myTimer.card1;
                                    LinkCard myCard = myTimer.card2;

                                    if (myCard.Value == mySelectCard.Value)
                                    {
                                        this.Children.Remove(linkLine);
                                        this.Children.Remove(myCard);
                                        this.Children.Remove(mySelectCard);
                                        //this.Children.Remove(combo);

                                        // 重列
                                        moveNode(myCard.X, myCard.Y, arrangeType);
                                        moveNode(mySelectCard.X, mySelectCard.Y, arrangeType);


                                        //检查是否需要重排
                                        if (FindCouple() == null)
                                        {
                                            //重排
                                            ReArrange();
                                        }
                                        mySelectCard = null;
                                        myCard = null;
                                        myTimer.card1 = null;
                                        myTimer.card2 = null;
                                    }
                                    else
                                    {
                                        this.Children.Remove(linkLine);
                                        //this.Children.Remove(combo);
                                    }
                                }
                            };
                            timer.Start();

                            currentClearCount += 2;
                            //GamePage.Instance.Combo();
                            if (currentClearCount >= cardCount)
                            {
                                GamePage.Instance.WinTheStage();
                            }
                            SoundManager.PlayEffect(SoundManager.Clear);
                        }
                        else
                        {
                            selectCard.SetUnSelectedCard();
                            selectCard = card;
                            card.SetSelectedCard();
                            SoundManager.PlayEffect(SoundManager.Click);
                        }
                    }
                    else
                    {
                        selectCard.SetUnSelectedCard();
                        selectCard = card;
                        card.SetSelectedCard();
                        SoundManager.PlayEffect(SoundManager.Click);
                    }
                }
            }
        }

        private void SetLinkLine(int x1, int y1, int x2, int y2)
        {
            linkLine.Points.Clear();

            if (LLKLogicHelper.Type == 1)
            {
                //判断横竖
                if (x1 == x2)
                {
                    linkLine.Stroke = ib2;
                }
                else
                {
                    linkLine.Stroke = ib3;
                }

                //直线
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(x2, y2));


            }
            else if (LLKLogicHelper.Type == 2)
            {
                //one conor
                linkLine.Stroke = ib1;
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX1, LLKLogicHelper.lineY1));
                linkLine.Points.Add(GetPoint(x2, y2));

            }
            else if (LLKLogicHelper.Type == 3)
            {
                //two conor
                linkLine.Stroke = ib1;
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX1, LLKLogicHelper.lineY1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX2, LLKLogicHelper.lineY2));
                linkLine.Points.Add(GetPoint(x2, y2));

            }

            if (!this.Children.Contains(linkLine))
            {
                this.Children.Add(linkLine);
            }
        }


        private Point GetPoint(int x1, int y1)
        {
            Point p = new Point();
            p.X = ((y1 - 1) * perHeight) + perHeight / 2.0;
            p.Y = ((x1 - 1) * perWidth) + perWidth / 2.0;

            return p;
        }

        /// <summary>
        /// 模拟游戏数据
        /// </summary>
        private void RamdomGameData()
        {
            //数据需要大一圈
            gameData = new int[rowCount + 2, columnCount + 2];
            int sum = rowCount * columnCount;

            for (int i = 0; i < rowCount + 2; i++)
            {
                for (int j = 0; j < columnCount + 2; j++)
                {
                    //清空数据
                    gameData[i, j] = -1;
                }
            }

            int temp = 0;
            for (int index = 0; index < sum / 2; index++)
            {
                temp = temp % itemChangeBase;
                if (temp > 19)
                {
                    MessageBox.Show("LinkCard index 超出");
                }

                for (int i = 0; i < 2; i++)
                {
                    int randomI = r.Next(1, rowCount + 1);
                    int randomJ = r.Next(1, columnCount + 1);
                    while (gameData[randomI, randomJ] != -1)
                    {
                        randomI = r.Next(1, rowCount + 1);
                        randomJ = r.Next(1, columnCount + 1);
                    }
                    gameData[randomI, randomJ] = temp + itemStartBase;
                }
                temp++;
            }
        }

        public void ReArrange()
        {
            ArrangeJob();

            while (FindCouple() == null && GamePage.Instance.gameStatus == 1)
            {
                ArrangeJob();
            }

            RefreshCards();
        }

        private void ArrangeJob()
        {
            // 重新洗牌，并修改LLKBlock对象中的Location
            // 找到所有没有被消除的块
            List<int> iList = new List<int>();
            List<int> jList = new List<int>();
            for (int i = 1; i < rowCount + 1; i++)
            {
                for (int j = 1; j < columnCount + 1; j++)
                {
                    if (gameData[i, j] >= 0)
                    {
                        iList.Add(i);
                        jList.Add(j);
                    }
                }
            }

            // 随机进行互换
            int halfCount = iList.Count / 2;
            for (int k = 0; k < halfCount; k++)
            {
                int i1 = iList[k];
                int j1 = jList[k];
                int randomK = halfCount + r.Next(halfCount);
                int i2 = iList[randomK];
                int j2 = jList[randomK];

                // 进行互换
                int temp = gameData[i1, j1];
                gameData[i1, j1] = gameData[i2, j2];
                gameData[i2, j2] = temp;
            }
        }

        /// <summary>
        /// 使用提示道具
        /// </summary>
        public bool UseFind()
        {
            var info = FindCouple();
            if (info != null)
            {
                //找到了
                LinkCard c1 = linkCards[info.X1 * columnCount + info.Y1];
                LinkCard c2 = linkCards[info.X2 * columnCount + info.Y2];
                c1.SetFind();
                c2.SetFind();
                return true;
            }
            return false;
        }

        /// <summary>
        /// 找到可以连接的一对
        /// </summary>
        /// <returns>如果没有找到 返回null</returns>
        private FindCardInfo FindCouple()
        {
            for (int i1 = 1; i1 <= rowCount + 1; i1++)
            {
                for (int j1 = 1; j1 <= columnCount + 1; j1++)
                {
                    if (gameData[i1, j1] >= 0)
                    {
                        for (int i2 = i1; i2 <= rowCount + 1; i2++)
                        {
                            for (int j2 = 1; j2 <= columnCount + 1; j2++)
                            {
                                if (i1 != i2 || j1 != j2)
                                {
                                    if (gameData[i1, j1] == gameData[i2, j2])
                                    {
                                        //尝试连接下
                                        if (LLKLogicHelper.CanEliminate(gameData, i1, j1, i2, j2, rowCount, columnCount))
                                        {
                                            //找到了，返回
                                            FindCardInfo result = new FindCardInfo();
                                            result.X1 = i1;
                                            result.Y1 = j1;
                                            result.X2 = i2;
                                            result.Y2 = j2;
                                            return result;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }


            return null;
        }


        #region MoveNode

        public void moveNode(int i, int j,
            GameArrangeType arrangeType)
        {
            switch (arrangeType)
            {
                case GameArrangeType.Left:
                    MoveLeft(i);
                    break;
                case GameArrangeType.Right:
                    MoveRight(i);
                    break;
                case GameArrangeType.Bottom:
                    MoveBottom(j);
                    break;
                case GameArrangeType.Top:
                    MoveTop(j);
                    break;
                case GameArrangeType.TopBottom:
                    MoveTopBottom(j);
                    break;
                case GameArrangeType.LeftRight:
                    MoveLeftRight(i);
                    break;
                default:
                    break;
            }
        }

        private void MoveTopBottom(int column)
        {
            //TopPart
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();
            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int i = 1; i < rowCount / 2 + 1; i++)
            {
                int data = gameData[i, column];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;
                    findInfo.X2 = -1;
                    findInfo.Y2 = -1;

                    for (int ii = i + 1; ii < rowCount / 2 + 1; ii++)
                    {
                        int tempData = gameData[ii, column];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = i;
                            findInfo.Y1 = column;
                            findInfo.X2 = ii;
                            findInfo.Y2 = column;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1 && findInfo.X2 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //BottomPart
            for (int i = rowCount; i > rowCount / 2; i--)
            {
                int data = gameData[i, column];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;
                    findInfo.X2 = -1;
                    findInfo.Y2 = -1;

                    for (int ii = i - 1; ii > rowCount / 2; ii--)
                    {
                        int tempData = gameData[ii, column];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = i;
                            findInfo.Y1 = column;
                            findInfo.X2 = ii;
                            findInfo.Y2 = column;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1 && findInfo.X2 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void MoveTop(int column)
        {
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();

            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int i = 1; i < rowCount + 1; i++)
            {
                int data = gameData[i, column];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;
                    findInfo.X2 = -1;
                    findInfo.Y2 = -1;

                    for (int ii = i + 1; ii < rowCount + 1; ii++)
                    {
                        int tempData = gameData[ii, column];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = i;
                            findInfo.Y1 = column;
                            findInfo.X2 = ii;
                            findInfo.Y2 = column;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1 && findInfo.X2 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void MoveBottom(int column)
        {
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();

            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int i = rowCount; i > 0; i--)
            {
                int data = gameData[i, column];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;
                    findInfo.X2 = -1;
                    findInfo.Y2 = -1;

                    for (int ii = i - 1; ii > 0; ii--)
                    {
                        int tempData = gameData[ii, column];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = i;
                            findInfo.Y1 = column;
                            findInfo.X2 = ii;
                            findInfo.Y2 = column;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1 && findInfo.X2 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void MoveLeftRight(int row)
        {
            //LeftPart
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();

            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int j = 1; j < columnCount / 2 + 1; j++)
            {
                int data = gameData[row, j];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;

                    for (int jj = j + 1; jj < columnCount / 2 + 1; jj++)
                    {
                        int tempData = gameData[row, jj];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = row;
                            findInfo.Y1 = j;
                            findInfo.X2 = row;
                            findInfo.Y2 = jj;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //RightPart
            for (int j = columnCount; j > columnCount / 2; j--)
            {
                int data = gameData[row, j];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;

                    for (int jj = j - 1; jj > columnCount / 2; jj--)
                    {
                        int tempData = gameData[row, jj];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = row;
                            findInfo.Y1 = j;
                            findInfo.X2 = row;
                            findInfo.Y2 = jj;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void MoveRight(int row)
        {
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();

            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int j = columnCount; j > 0; j--)
            {
                int data = gameData[row, j];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;

                    for (int jj = j - 1; jj > 0; jj--)
                    {
                        int tempData = gameData[row, jj];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = row;
                            findInfo.Y1 = j;
                            findInfo.X2 = row;
                            findInfo.Y2 = jj;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void MoveLeft(int row)
        {
            List<FindCardInfo> needToExchange = new List<FindCardInfo>();

            // 找到一个空的，往后寻找，找到替换，没找到break
            for (int j = 1; j < columnCount + 1; j++)
            {
                int data = gameData[row, j];
                if (data < 0)
                {
                    FindCardInfo findInfo = new FindCardInfo();
                    findInfo.X1 = -1;
                    findInfo.Y1 = -1;

                    for (int jj = j + 1; jj < columnCount + 1; jj++)
                    {
                        int tempData = gameData[row, jj];
                        if (tempData >= 0)
                        {
                            findInfo.X1 = row;
                            findInfo.Y1 = j;
                            findInfo.X2 = row;
                            findInfo.Y2 = jj;
                            break;
                        }
                    }
                    if (findInfo.X1 != -1)
                    {
                        //更新gameData
                        int temp = gameData[findInfo.X1, findInfo.Y1];
                        gameData[findInfo.X1, findInfo.Y1] = gameData[findInfo.X2, findInfo.Y2];
                        gameData[findInfo.X2, findInfo.Y2] = temp;
                        needToExchange.Add(findInfo);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // 互换并更新界面
            ExchangeLinkCard(needToExchange);
        }

        private void ExchangeLinkCard(List<FindCardInfo> needToExchange)
        {
            foreach (var item in needToExchange)
            {
                //做动画改变LinkCard位置
                LinkCard card = linkCards[item.X2 * columnCount + item.Y2];

                Storyboard storyBoard = new Storyboard();
                Duration duration = GetDuration(item);
                DoubleAnimation daX = new DoubleAnimation();
                daX.Duration = duration;
                daX.To = (item.X1 - 1) * perHeight;
                DoubleAnimation daY = new DoubleAnimation();
                daY.Duration = duration;
                daY.To = (item.Y1 - 1) * perWidth;

                Storyboard.SetTarget(storyBoard, card);
                Storyboard.SetTargetProperty(daX, new PropertyPath(Canvas.TopProperty));
                Storyboard.SetTargetProperty(daY, new PropertyPath(Canvas.LeftProperty));
                storyBoard.Children.Add(daX);
                storyBoard.Children.Add(daY);

                storyBoard.Begin();

                //Canvas.SetTop(card, (item.X2 - 1) * perWidth);
                //Canvas.SetLeft(card, (j - 1) * perHeight);

                card.X = item.X1;
                card.Y = item.Y1;
                linkCards[item.X1 * columnCount + item.Y1] = card;
            }
        }

        private Duration GetDuration(FindCardInfo item)
        {
            int offset;
            int x = Math.Abs(item.X1 - item.X2);
            int y = Math.Abs(item.Y1 - item.Y2);
            if (x > y)
            {
                offset = x;
            }
            else
            {
                offset = y;
            }
            return new Duration(TimeSpan.FromMilliseconds(45 * offset));
        }

        #endregion
    }
}
